傳入參數後,藉由 switch-case 來建立一系列擁有相同親代的物件
作為入門 Design Pattern 的第一個模式,Simple Factory Method 本身不屬於「物件導向設計模式」所列的 23 個模式內,其價值在於了解「簡單」、「常用」的寫法也屬於設計模式的一種。
Simple Factory Method 的作法是:
switch-case 後決定生產哪個物件。產品親代:PETBottle
public abstract class PETBottle {
    protected String smell = "";
    protected String color = "";
    public void setBottle(String smell, String color) {
        this.smell = smell;
        this.color = color;
    }
    public abstract String getTaste();
}
產品子代:Coke、Water、OrangeJuice
public class Coke extends PETBottle {
    @Override
    public String getTaste() {
        return "這瓶可樂的顏色:" + color + ",香味是:" + smell;
    }
}
public class Water extends PETBottle {
    @Override
    public String getTaste() {
        return "這瓶水的顏色:" + color + ",香味是:" + smell;
    }
}
public class OrangeJuice extends PETBottle {
    @Override
    public String getTaste() {
        return "這瓶柳橙汁的顏色:" + color + ",香味是:" + smell;
    }
}
工廠:PETBottleFactory
public class PETBottleFactory {
    public static PETBottle getPETBottle(String option) throws Exception {
        PETBottle bottle = null;
        switch (option) {
            case "coke":
                bottle = new Coke();
                break;
            case "Water":
                bottle = new Water();
                break;
            case "OrangeJuice":
                bottle = new OrangeJuice();
                break;
            default:
                throw new Exception("輸入錯誤");
        }
        return bottle;
    }
}
實作:
public class PETBottleSimpleFactorySample {
    public static void main(String[] args) throws Exception {
        String option = "coke";
        String smell = "甜甜的";
        String color = "黑黑的";
        PETBottle bottle = PETBottleFactory.getPETBottle(option);
        bottle.setBottle(smell, color);
        System.out.println(bottle.getTaste());
    }
}
受限於 JavaScript 沒有虛擬型別、無法限制型別。
產品親代:PETBottle
/** @abstract */
class PETBottle {
  constructor() {
    this.smell = '';
    this.color = '';
  }
  setBottle(smell, color) {
    this.smell = smell;
    this.color = color;
  }
  getTaste() { return; }
}
產品子代:Coke、Water、OrangeJuice
class Coke extends PETBottle {
  /** @override */
  getTaste() {
    return "這瓶可樂的顏色:" + this.color + ",香味是:" + this.smell;
  }
}
class Water extends PETBottle {
  /** @override */
  getTaste() {
    return "這瓶水的顏色:" + this.color + ",香味是:" + this.smell;
  }
}
class OrangeJuice extends PETBottle {
  /** @override */
  getTaste() {
    return "這瓶柳橙汁的顏色:" + this.color + ",香味是:" + this.smell;
  }
}
工廠:PETBottleFactory
class PETBottleFactory {
  static getPETBottle(option) {
    /** @type PETBottle */
    let bottle = null;
    switch (option) {
      case "coke":
        bottle = new Coke();
        break;
      case "Water":
        bottle = new Water();
        break;
      case "OrangeJuice":
        bottle = new OrangeJuice();
        break;
      default:
        throw new Error("輸入錯誤");
    }
    return bottle;
  }
}
實作:
const PETBottleSimpleFactorySample = () => {
  const option = "coke";
  const smell = "甜甜的";
  const color = "黑黑的";
  const bottle = PETBottleFactory.getPETBottle(option);
  bottle.setBottle(smell, color);
  console.log(bottle.getTaste());
};
PETBottleSimpleFactorySample();
Simple Factory Method 最適合當作第一個入門的模式,在於簡單好懂:
缺點則是要增加子代項目時,必須修改「生產者物件」,也就是 switch 的區塊,這點會破壞 SOLID 的 OCP,每次修改程式碼時,不該動到既有的程式碼。
因為這一點,才有後續兩個與 Factory 有關的模式。